package com.example.mysql.学习笔记.高级.数据库的优化之索引.数据库的设计规范之范式;

public class 数据库对象编写建议 {
}
/**
 * 10.数据库对象编写建议
 * 前面我们讲了数据库的设计规范，下面给出的这些规范适用于大多数公司，
 * 按照下面的规范来使用数据库,这样数据库可以发挥出更高的性能。
 *
 * 10.1关于库
 * 1. [强制]库的名称必须控制在32个字符以内，
 *          只能使用英文字母、数字和下划线,建议以英文字母开头。
 * 2. [强制]库名中英文-律小写，不同单词采用下划线分割。须见名知意。
 * 3. [强制]库的名称格式:业务系统名称子系统名。
 * 4. [强制]库名禁止使用关键字 (如type,order等)。
 * 5. [强制]创建数据库时必须显式指定字符集，并且字符集只能是utf8或者utf8mb4。
 *    创建数据库SQL举例: CREATE DATABASE crm_fund DEFAULT CHARACTER SET 'utf8' ;
 * 6. [建议]对于程序连接数据库账号，遵循权限最小原则
 *     使用数据库账号只能在一个DB 下使用，不准跨库。程序使用的账号原则上不准有drop权限。
 * 7. [建议]临时库以 tmp_为前缀, 并以日期为后缀;
 *         备份库以bak_为前缀，并以日期为后缀。
 */
/**
 * 10.2关于表、列
 * 1. [强制] 表和列的名称必须控制在32个字符以内，
 *          表名只能使用英文字母、数字和下划线,建议以英文字母开头。
 * 2. [强制] 表名、列名一律小写，不同单词采用下划线分割。 须见名知意。
 * 3. [强制] 表名要求有模块名强相关， 同-模块的表名尽量使用统一前缀。
 *          比如: crm _fund_item
 * 4. [强制] 创建表时必须 显式指定字符集为utf8或utf8mb4。
 * 5. [强制]表名、列名禁止使用关键字(如type,order等)。
 * 6. [强制]创建表时必须显式指定表存储引擎类型。如无特殊需求，一律为InnoDB。
 * 7. [强制] 建表必须有comment。
 * B. [强制]字段命名应尽可能使用表达实际含义的英文单词或缩写。
 *         如:公司ID, 不要使用corporation_id,而用corp_ id即可。
 * 9. [强制]布尔值类型的字段命名为is. 描述。
 *         如member表上表示是否为enabled的会员的字段命名为is_enabled。
 * 10. [强制] 禁止在数据库中存储图片、文件等大的二进制数据通常文件很大，
 *           短时间内造成数据量快速增长，数据库进行数据库读取时，通常会进行大量的随机I/O操作,
 *           文件很大时，I/O操作很耗时。通常存储于文件服务器，数据库只存储文件地址信息。
 * 11. [建议] 建表时关于主键:表必须有 主键
 *      (1)强制要求主键为id,类型为int或bigint, 且为auto_ increment
 *         建议使用unsigned无符号型。
 *      (2)标识表里每一行主体的字段不要设为主键，
 *         建议设为其他字段如user_id, order_id等，并建立unique key索引。(唯一)
 *         因为如果设为主键且主键值为随机插入，则会导致innodb内部页分裂和大量随机I/O，性能下降。
 * 12. [建议]核心表(如用户表)必须有行数据的创建时间字段(create_time)
 *                             和最后更新时间字段(update_ time) ，便于查问题。
 * 13. [建议] 表中所有字段尽量都是NOT NULL 属性,业务可以根据需要定义DEFAULT值。
 *          因为使用NULL值会存在每一行都会占用额外存储空间、数据迁移容易出错、聚合函数计算结果偏差等问题。
 * 14. [建议] 所有存储相同数据的列名和列类型必须一致(一般作为关联列，
 *           如果查询时关联列类型不一致会自动进行数据类型隐式转换，
 *           会造成列上的索引失效，导致查询效率降低)。
 * 15. [建议]中间表(或临时表)用于保留中间结果集，名称以tmp_开头。
 *          备份表用于备份或抓取源表快照，名称以bak_开头。中间表和备份表定期清理。
 * 17. [建议] 创建表时，可以使用可视化工具。这样可以确保表、字段相关的约定都能设置上。
 * 实际上，我们通常很少自己写DDL语句，可以使用一些可视化工具来创建和操作数据库和数据表。
 * 可视化工具除了方便，还能直接帮我们将数据库的结构定义转化成SQL语言,
 * 方便数据库和数据表结构的导出和导入。
 */
/**
 * 10.3关于索引
 * 1. [强制] InnoDB表必须主键为id int/bigint auto_increment, 且主键值禁止被更新。
 * 2. [强制] InnoDB和MyISAM存储引擎表，索引类型必须为BTREE。（B+数）
 * 3. [建议] 主键的名称以pk_开头,唯一键以uni_或uk_开头，普通索引以idx_开头，
 *         一律使用小写格式，以字段的名称或缩写作为后缀。
 * 4. [建议] 多单词组成的columnname,取前几个单词首字母，加末单词组成column_name。
 *          如: sample表member_id. 上的索引: idx_sample_mid。
 * 5. [建议]单个表上的索引个数不能超过6个。
 * 6. [建议]在建立索引时，多考虑建立联合索引,并把区分度最高的字段放在最前面。
 * 7. [建议]在多表JOIN的SQL里，保证被驱动表的连接列上有索引，这样JOIN执行效率最高。
 * 8. [建议]建表或加索引时，保证表里互相不存在冗余索引。
 *         比如:如果表里已经存在key(a,b),则key(a)为冗余索引，需要删除。
 *
 */
/**
 * 10.4 SQL编写
 * 1. [强制] 程序端SELECT语句必须指定具体字段名称,禁止写成*。
 * 2. [建议]程序端insert语句指定具体字段名称,不要写成INSERT INTO t1 VALUES(...)。
 * 3. [建议]除静态表或小表 (100行以内)，DML语句必须有WHERE条件， 且使用索引查找。
 * 4. [建议] INSERT IN...VALUES(XX),(XX).. 这里XX的值不要超过5000个。
 *         值过多虽然上线很快,但会引起主从同步延迟。
 * 5. [建议] SELECT语句不要使用UNION,推荐使用UNION ALL, 并且UNION子句个数限制在5个以内。
 *                            (UNION会产生临时表)
 * 6. [建议]线上环境，多表JOIN不要超过5个表。
 * 7. [建议]减少使用ORDER BY,和业务沟通能不排序就不排序，或将排序放到程序端去做。
 *         ORDER BY、GROUP BY、DISTINCT 这些语句较为耗费CPU，数据库的CPU资源是极其宝贵的。
 * 8. [建议]包含了ORDER BY、 GROUP BY、 DISTINCT这些查询的语句，
 *         WHERE条件过滤出来的结果集请保持在1000行以内，否则SQL会很慢。
 * 9. [建议]对单表的多次alter操作必须合并为一次对于超过10W行的大表进行alter table,
 *         必须经过DBA审核，并在业务低峰期执行，多个alter需整合在-起。
 *         因为alter table会产生表锁，期间阻塞对于该表的所有写入，对于业务可能会产生极大影响。
 * 10. [建议]批量操作数据时，需要控制事务处理间隔时间，进行必要的sleep。
 * 11. [建议]事务里包含SQL不超过5个。
 *          因为过长的事务会导致锁数据较久, MySQL内部缓存、连接消耗过多等问题。
 * 12.[建议]事务里更新语句尽量基于主键或UNIQUE KEY,如UPDATE... WHERE id=XX;
 *          否则会产生间隙锁，内部扩大锁定范围，导致系统性能下降，产生死锁。
 */
